#include "PlayerInfo.h"

PlayerInfo::PlayerInfo()
	:	m_mesh(nullptr), m_collisionBox(nullptr)
{

}

PlayerInfo::~PlayerInfo()
{

}

void PlayerInfo::Init(ID3D11Device* md3dDevice, XMFLOAT3 position, XMFLOAT3 velocity, ID3D11Buffer* cylinder_vb, ID3D11Buffer* cylinder_ib, Material* material)
{
	m_mesh = new BasicMesh(cylinder_vb, cylinder_ib, material, NULL,
		XMFLOAT3(0.0f, 0.5f, 0.0f), XMFLOAT3(0.0f, 0.0f, 0.0f), XMFLOAT3(1.0f, 1.0f, 1.0f),
		XMFLOAT3(1.0f, 1.0f, 1.0f), false);

	m_collisionBox = new AxisAlignedBox();
	m_collisionBox->Center = XMFLOAT3(0,0.5,0);
	m_collisionBox->Extents = XMFLOAT3(0.25, 1, 0.25);
}

void PlayerInfo::CheckMovementCollision(std::vector<InstanceMap*>* vInstanceMaps, std::vector<ModelData*>* vModelData,
	XMFLOAT3& inputVelocity, float dt)
{
	bool HasCollidedX = false;
	bool HasCollidedZ = false;

	XNA::AxisAlignedBox collisionBoxPlayer;
	XNA::AxisAlignedBox* pCollisionAABBWorld;

	std::vector<InstanceMap*>::iterator itIM = vInstanceMaps->begin();
	std::vector<ModelData*>::iterator itMD = vModelData->begin();

	for(itIM; itIM != vInstanceMaps->end(); itIM++, itMD++)
	{
		InstanceMap* instanceMap = *itIM;
		pCollisionAABBWorld = (*itMD)->GetAABBp();
			
		// Loop through ALL the instances in the scene.
		for (UINT i = 0; i < instanceMap->GetInstancedDataP()->size(); ++i)
		{
			if( pCollisionAABBWorld  != nullptr)
			{
				XNA::AxisAlignedBox worldBox = *pCollisionAABBWorld;

				vector<InstancedData>* pInstanceDataVec = instanceMap->GetInstancedDataP();

				float x = (*pInstanceDataVec)[i].World._41;
				float y = (*pInstanceDataVec)[i].World._42;
				float z = (*pInstanceDataVec)[i].World._43;

				worldBox.Center = XMFLOAT3(x, y, z);


				// Set the box for the player mesh
			
				collisionBoxPlayer = *m_collisionBox;


				// Test x component for collision
				collisionBoxPlayer.Center = GetPosition();
				collisionBoxPlayer.Center.x += inputVelocity.x;

				//if we havent already had and X collision
				if(HasCollidedX == false)
				{
					if( IntersectAxisAlignedBoxAxisAlignedBox(&worldBox, &collisionBoxPlayer) )
					{
						inputVelocity.x -= inputVelocity.x;
						HasCollidedX = true;
					}
				}



				// Test z component for collision
				collisionBoxPlayer.Center = GetPosition();
				collisionBoxPlayer.Center.z += inputVelocity.z;

				if(HasCollidedZ == false)
				{
					if( IntersectAxisAlignedBoxAxisAlignedBox(&worldBox, &collisionBoxPlayer) )
					{
							inputVelocity.z -= inputVelocity.z;
							HasCollidedZ = true;
					}
				}

				// if both x and z have collided, break from loop
				if(HasCollidedX && HasCollidedZ)
				{
					break;
				}
			}
		}
	}

	// Update the Player Position

	XMVECTOR XMVlastPos = XMLoadFloat3(&m_mesh->GetTranslation());
	XMVECTOR XMVinputVelocity = XMLoadFloat3(&inputVelocity);
	XMVECTOR XMVnewTrans = (XMVectorAdd(XMVlastPos, XMVinputVelocity));


	XMFLOAT3 f3newTrans;
	XMStoreFloat3(&f3newTrans, XMVnewTrans);

	m_mesh->SetTranslation(f3newTrans.x, f3newTrans.y, f3newTrans.z);
	
}

void PlayerInfo::Shutdown()
{
	// release and delete stuff
	SafeDelete(m_mesh);
}

//----------------------------------------------------------------------------------------------
// Getters and Setters
//----------------------------------------------------------------------------------------------
// Collision Box
void PlayerInfo::SetCollisionBox(AxisAlignedBox* collisionBox)
{
	m_collisionBox = collisionBox;
}

AxisAlignedBox* PlayerInfo::GetCollisionBox()
{
	return m_collisionBox;
}
//----------------------------------------------------------------------------------------------
// Mesh
void PlayerInfo::SetMesh(BasicMesh* mesh)
{
	m_mesh = mesh;
}

BasicMesh* PlayerInfo::GetMesh()
{
	return m_mesh;
}

//----------------------------------------------------------------------------------------------
// Position
XMFLOAT3 PlayerInfo::GetPosition()
{
	if(m_mesh != nullptr)
	{
		return m_mesh->GetTranslation();
	}
	else
		MessageBox(NULL, L"Player Mesh Not Set.", L"Player Mesh Error", MB_OK);
		return nullptr;
}

void PlayerInfo::SetPosition(XMFLOAT3 position)
{
	m_mesh->SetTranslation(position.x, position.y, position.z);
}